/*
    Copyright 2021 codenocold codenocold@qq.com
    Address : https://github.com/codenocold/dgm
    This file is part of the dgm firmware.
    The dgm firmware is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    The dgm firmware is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "pwm_curr.h"

uint16_t adc_vbus[1];
int16_t phase_a_adc_offset = 0;
int16_t phase_b_adc_offset = 0;
int16_t phase_c_adc_offset = 0;

void PWMC_init(void) {
    /* Disable ADC interrupt */
    //HAL_ADCEx_InjectedStop_IT(&hadc1);

    /* enable ADC0 */
    //adc_enable(ADC0);
    /* Wait ADC0 startup */
    HAL_Delay(1);
    /* ADC0 calibration */
    HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);

    /* ADC software trigger enable */
    //adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);

    /* ADC0 inject convert complete interrupt */
    HAL_ADCEx_InjectedStart_IT(&hadc1);

    /* enable ADC1 */
    //adc_enable(ADC1);
    /* Wait ADC1 startup */
    HAL_Delay(1);
    /* ADC1 calibration */
    HAL_ADCEx_Calibration_Start(&hadc2, ADC_SINGLE_ENDED);

    /* Hold TIMER0 counter when core is halted */
    //dbg_periph_enable(DBG_TIMER0_HOLD);

    /* Enable TIMER0 counter */
    //timer_enable(TIMER0);

    //timer_repetition_value_config(TIMER0, 1);

    /* Set all duty to 50% */
    set_a_duty(((uint32_t) HALF_PWM_PERIOD_CYCLES / (uint32_t) 2));
    set_b_duty(((uint32_t) HALF_PWM_PERIOD_CYCLES / (uint32_t) 2));
    set_c_duty(((uint32_t) HALF_PWM_PERIOD_CYCLES / (uint32_t) 2));

    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);
    HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);
    HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);
    HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);

    // 定时器通道4触发ADC采样
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);

    /* Main PWM Output Enable */
    //timer_primary_output_config(TIMER0, ENABLE);
}

void PWMC_SwitchOnPWM(void) {
    /* Set all duty to 50% */
    set_a_duty(((uint32_t) HALF_PWM_PERIOD_CYCLES / (uint32_t) 2));
    set_b_duty(((uint32_t) HALF_PWM_PERIOD_CYCLES / (uint32_t) 2));
    set_c_duty(((uint32_t) HALF_PWM_PERIOD_CYCLES / (uint32_t) 2));

    /* wait for a new PWM period */
//    timer_flag_clear(TIMER0, TIMER_FLAG_UP);
//    while (RESET == timer_flag_get(TIMER0, TIMER_FLAG_UP)) {
//    };
//    timer_flag_clear(TIMER0, TIMER_FLAG_UP);

    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);
}

void PWMC_SwitchOffPWM(void) {
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);
    HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);
    HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);
    HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);

    /* wait for a new PWM period */
//    timer_flag_clear(TIMER0, TIMER_FLAG_UP);
//    while (RESET == timer_flag_get(TIMER0, TIMER_FLAG_UP)) {
//    };
//    timer_flag_clear(TIMER0, TIMER_FLAG_UP);
}

void PWMC_TurnOnLowSides(void) {
    /* Set all duty to 0% */
    set_a_duty(0);
    set_b_duty(0);
    set_c_duty(0);

    /* wait for a new PWM period */
//    timer_flag_clear(TIMER0, TIMER_FLAG_UP);
//    while (RESET == timer_flag_get(TIMER0, TIMER_FLAG_UP)) {
//    };
//    timer_flag_clear(TIMER0, TIMER_FLAG_UP);

    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);
}
